package com.pactera.asmp.server.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pactera.asmp.server.common.constants.ResultCode;
import com.pactera.asmp.server.common.exception.CustomException;
import com.pactera.asmp.server.dao.*;
import com.pactera.asmp.server.entity.*;
import com.pactera.asmp.server.pojo.*;
import com.pactera.asmp.server.utils.AssertUtil;
import com.pactera.asmp.server.utils.MinioUtils;
import com.pactera.asmp.server.utils.PageDataResult;

import org.apache.commons.beanutils.ConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;

/**
 * @ProjectName: asmp-server
 * @Package com.pactera.asmp.server.service
 * @ClassName: TestReportServiceImpl
 * @Description:
 * @Date 2020/08/06 13:54
 * @Author lvzhiqiang
 * @Version 1.0
 */
@Service
@Slf4j
public class TestReportServiceImpl implements ITestReportService {

    public static final String TASKID_NOTNULL = "任务Id不允许为空";
    public static final String SCRIPTID_NOTNULL = "脚本Id不允许为空";
    @Autowired
    private TestReportMapper mTestReportMapper;

    @Autowired
    private ProjectModuleMapper projectModuleMapper;

    @Autowired
    private IScriptInfoServcie iScriptInfoServcie;

    @Autowired
    @Lazy
    private TaskService taskService;

    @Autowired
    private IRedisService iRedisService;

    @Autowired
    private ScriptInfoHistoryMapper scriptInfoHistoryMapper;

    @Resource
    private TaskMapper taskMapper;

    @Autowired
    private TestReportErrorVideoInfoMapper testReportErrorVideoInfoMapper;

    @Autowired
    private TestReportApplicationResponseTimeMapper testReportApplicationResponseTimeMapper;

//    @Autowired
//    private FileTemplate fileTemplate;

    @Autowired
    private MinioUtils minioUtils;

    private final static String REDIS_KEY_FAIL_REPORT = "FAIL_REPORT:";
    private final static int REDIS_CACHE_EXPIRE = 60*60*1;  // 1小时


    @Override
    public boolean insert(TestReport testReport) {
        testReport.setCreateTime(LocalDateTime.now());
        return mTestReportMapper.insert(testReport) > 0 ;
    }

    @Override
    public boolean insert(TestReportDTO testReportDTO) {
        testReportDTO.setCreateTime(LocalDateTime.now());
        return mTestReportMapper.insert2(testReportDTO) > 0;
    }

    @Override
    public boolean delete(List<Integer> datas) {
        return mTestReportMapper.deleteByPrimaryKeys(datas) > 0;
    }

    @Override
    public boolean update(TestReport testReport) {
        return mTestReportMapper.update(testReport) > 0 ;
    }

    @Autowired
    private TaskDeviceMemoryLogMapper taskDeviceMemoryLogMapper;

    @Autowired
    private TaskDeviceTopLogMapper taskDeviceTopLogMapper;


    @Override
    public PageDataResult select(TestReportSearchDTO testReportSearchDTO) {
        PageDataResult pageDataResult = new PageDataResult();
        PageHelper.startPage(testReportSearchDTO.getPage(), testReportSearchDTO.getLimit());
        List<TestReport> list = mTestReportMapper.select2(testReportSearchDTO);
        if(!CollectionUtils.isEmpty(list)){
            for(TestReport testReport : list ){
                //[{"anrCount":0,"crashCount":2,"packagesName":"com.example.partnersupportsampletvinput"},{"anrCount":0,"crashCount":0,"packagesName":"com.gientech.user"}]
                if(!StringUtils.isEmpty(testReport.getMonkeyReport())){
                    List<JSONObject> packageList = JSONObject.parseObject(testReport.getMonkeyReport(),List.class);
                    for(JSONObject record : packageList){
                        String name = record.getString("packagesName");
                        TaskDeviceTopLogExample taskDeviceTopLogExample = new TaskDeviceTopLogExample();
                        taskDeviceTopLogExample.createCriteria().andTaskIdEqualTo(testReportSearchDTO.getTaskId().longValue()).andNameEqualTo(name);
                        List<TaskDeviceTopLog> taskDeviceTopLogs = taskDeviceTopLogMapper.selectByExample(taskDeviceTopLogExample);
                        if(!CollectionUtils.isEmpty(taskDeviceTopLogs)){
                            int sum = 0;
                            for(TaskDeviceTopLog log : taskDeviceTopLogs){
                                sum = sum + log.getCpu();
                            }
                            record.put("cpu",(sum/taskDeviceTopLogs.size()));
                        }else{
                            record.put("cpu","0");
                        }

                        TaskDeviceMemoryLogExample example = new TaskDeviceMemoryLogExample();
                        example.createCriteria().andTaskIdEqualTo(testReportSearchDTO.getTaskId().longValue()).andNameEqualTo(name);
                        List<TaskDeviceMemoryLog> taskDeviceMemoryLogs = taskDeviceMemoryLogMapper.selectByExample(example);
                        if(!CollectionUtils.isEmpty(taskDeviceMemoryLogs)){
                            int sum = 0;
                            for(TaskDeviceMemoryLog log : taskDeviceMemoryLogs){
                                sum = sum + log.getPss();
                            }
                            record.put("memory",(sum/taskDeviceMemoryLogs.size()));
                        }else{
                            record.put("memory","0");
                        }
                    }
                    testReport.setMonkeyReport(JSONObject.toJSONString(packageList));
                }
            }
        }
        PageInfo<TestReport> pageInfo = new PageInfo<>(list);
        pageDataResult.setTotals(Long.valueOf(pageInfo.getTotal()).intValue());
        pageDataResult.setList(list);
        return pageDataResult;
    }

    @Override
    public List<SelectTestReportResult> selectAll(Integer taskId) {
        AssertUtil.notNull(taskId, TASKID_NOTNULL);

        return  mTestReportMapper.selectAll(taskId);
    }

    @Override
    @Transactional
    public int insertBatch(List<TestReportDTO> reports) {
        if(CollectionUtils.isEmpty(reports)) return  0;
        reports.stream().forEach(report -> report.setCreateTime(LocalDateTime.now()));
        return mTestReportMapper.inserBatch(reports);
    }

    @Override
    public List<TaskReportChartVO> getTaskReportCategoryChart(Integer taskId) {
        AssertUtil.notNull(taskId,TASKID_NOTNULL);
        List<TaskReportChartVO> taskReportChart = mTestReportMapper.getTaskReportCategoryChart(taskId);
        return taskReportChart == null?new ArrayList<>():taskReportChart;
    }

    @Override
    public List<TaskReportChartVO> getTaskReportCategoryChart2(List<Integer> idsList,List<ScriptInfo2> scriptInfos) {
        if(CollectionUtils.isEmpty(idsList)) return new ArrayList<>();
        if(CollectionUtils.isEmpty(scriptInfos)) return new ArrayList<>();

        Map<String,Integer> chartData = new HashMap<>();

        boolean exist;
        for(Integer scriptId : idsList){
            exist = false;
            for(ScriptInfo2 scriptInfo : scriptInfos){
                if(scriptId.intValue() == scriptInfo.getId().intValue()){
                    exist = true;
                    increasingChartData(scriptInfo.getScriptCategory(),chartData);
                    break;
                }
            }
            if(!exist){
                increasingChartData("",chartData);
            }
        }
        return chartData.entrySet().stream().map(e -> new TaskReportChartVO(e.getKey(),e.getValue())).collect(Collectors.toList());
    }

    private void increasingChartData(String key,Map<String,Integer> chartData){
        if(chartData == null) chartData = new HashMap<>();

        boolean exist = chartData.containsKey(key);
        if(!exist){
            chartData.put(key,1);
        }
        else{
            chartData.put(key,chartData.get(key) +1);
        }
    }

    @Override
    public List<TaskReportChartVO> getTaskReportModuleChart(Integer taskId) {
        AssertUtil.notNull(taskId,TASKID_NOTNULL);
        List<TaskReportChartVO> taskReportChart = mTestReportMapper.getTaskReportModuleChart(taskId);
        return taskReportChart == null?new ArrayList<>():taskReportChart;
    }

    @Override
    public List<TaskReportChartVO> getTaskReportModuleChart2(List<Integer> idsList,List<ScriptInfo2> scriptInfos) {
        if(CollectionUtils.isEmpty(idsList)) return new ArrayList<>();
        if(CollectionUtils.isEmpty(scriptInfos)) return new ArrayList<>();

        Map<String,Integer> chartData = new HashMap<>();
        boolean exist;
        for(Integer scriptId : idsList){
            exist = false;
            for(ScriptInfo2 scriptInfo : scriptInfos){
                if(scriptId.intValue() == scriptInfo.getId().intValue()){
                    exist = true;
                    increasingChartData(scriptInfo.getProModuleName(),chartData);
                    break;
                }
            }
            if(!exist){
                increasingChartData("",chartData);
            }
        }
        return chartData.entrySet().stream().map(e -> new TaskReportChartVO(e.getKey(),e.getValue())).collect(Collectors.toList());
    }

    @Override
    public List<TaskReportListVO> getTaskReportList(List<TaskDTO> taskDTOs) {
        TaskDTO taskHistoryById = taskDTOs.get(0);
        if(taskHistoryById == null) return new ArrayList<>();

        String scriptIds = taskHistoryById.getScriptIds();
        if(StringUtils.isEmpty(scriptIds))  return new ArrayList<>();

        // 获取各个模块需要执行的次数
        // Map<模块ID,需要执行的次数>
        Map<Integer,Integer> moduleCount = this.getScriptModuleByIds(scriptIds, taskHistoryById.getExeNumber());
        if(moduleCount == null || moduleCount.size() == 0) throw new CustomException(ResultCode.DATA_IS_WRONG);

        List<ProjectModuleDTO> projectModule = null;
        Map<Integer, ProjectModuleDTO> projectModuleMap= null;
        if(taskHistoryById.getProjectId() != null) {
            ProjectModuleSearch search = new ProjectModuleSearch();
            search.setProjectId(taskHistoryById.getProjectId());
            projectModule = projectModuleMapper.select(search);
            if(!CollectionUtils.isEmpty(projectModule)) {
                projectModuleMap = projectModule.stream().collect(Collectors.toMap(ProjectModuleDTO::getId, x -> x));
            }
        }

        List<Integer> taskIds = new ArrayList<>();
        for (TaskDTO TaskDTO : taskDTOs) {
            taskIds.add(TaskDTO.getId());
        }

        List<TaskReportList> taskReportList = mTestReportMapper.getTaskReportList(taskIds);
        if(taskReportList == null) return new ArrayList<>();
//      project_module_id     status      count
//      1                     1	        17
//      1                     0	        1

        Map<Integer, List<TaskReportList>> taskReportListMap =  taskReportList.stream().collect(Collectors.groupingBy(TaskReportList::getModuleId));
        List<TaskReportListVO> taskReportListVOList = new ArrayList<>();
        for(Integer moduleId : moduleCount.keySet()) {
            List<TaskReportList> taskReportLists= taskReportListMap.get(moduleId);
            TaskReportListVO taskReportListVO = new TaskReportListVO();
            taskReportListVO.setModuleId(moduleId);
            if(null != projectModuleMap && projectModuleMap.containsKey(moduleId)) {
                taskReportListVO.setModuleName(projectModuleMap.get(moduleId).getName());
            }
            Integer pass = 0;
            Integer fail = 0;
            if(!CollectionUtils.isEmpty(taskReportLists)) {
                Optional<TaskReportList> passOptinal = taskReportLists.stream().filter(r -> r.getStatus().intValue() == 1).findFirst();
                Optional<TaskReportList> failOptinal = taskReportLists.stream().filter(r -> r.getStatus().intValue() == 0).findFirst();
                if(passOptinal.isPresent()) {
                    pass = passOptinal.get().getCount();
                }
                if(failOptinal.isPresent()) {
                    fail = failOptinal.get().getCount();
                }
            }
            taskReportListVO.setPass(pass);
            taskReportListVO.setFail(fail);
            taskReportListVO.setNoExec(moduleCount.get(moduleId).intValue() - pass.intValue() - fail.intValue());
            taskReportListVOList.add(taskReportListVO);
        }

        return taskReportListVOList;
    }

    private Map<Integer, Integer> getScriptModuleByIds(String scriptIds, Integer exeNumber) {
        AssertUtil.hasText(scriptIds,"数据有据");
        String[] ids = scriptIds.split(",");
        Integer[] _ids = (Integer[]) ConvertUtils.convert(ids, Integer.class);

        Map<Integer, Integer> scriptModuleByIds = iScriptInfoServcie.getScriptModuleByIds(_ids); // map<脚本ID,模块ID>
        if(scriptModuleByIds == null) throw new CustomException(ResultCode.DATA_IS_WRONG);

        Map<Integer, Integer> result = new HashMap<>();

        Integer tmp_module_id;
        for (int i = 0; i < _ids.length; i++) {
            tmp_module_id = scriptModuleByIds.get(_ids[i]);
            if(result.containsKey(tmp_module_id)){
                result.put(tmp_module_id,result.get(tmp_module_id) + exeNumber);
            }
            else {
                result.put(tmp_module_id,exeNumber);
            }
        }
        return  result;
    }


    @Override
    public List<Integer> getScriptIdsByProjectId(Integer projectId) {
        AssertUtil.notNull(projectId,"项目Id不允许为空");

        List<String> scriptIds = mTestReportMapper.getScriptIdsByProjectId(projectId);
        if(CollectionUtils.isEmpty(scriptIds)) return new ArrayList<>();
        List<Integer> ids = new ArrayList<>();
        transIds(scriptIds,ids);
        return ids;
    }
    @Override
    public List<TaskReportChartVO> getProjectReportChartByCategory(List<Integer> scriptIds) {
        AssertUtil.notNull(scriptIds, SCRIPTID_NOTNULL);
        if(CollectionUtils.isEmpty(scriptIds)) return new ArrayList<>();

        List<TaskReportChartVO> projectReportChart = mTestReportMapper.getProjectReportChartByCategory(scriptIds);
        return projectReportChart == null?new ArrayList<>():projectReportChart;
    }
    @Override
    public List<TaskReportChartVO> getProjectReportChartByModule(List<Integer> scriptIds) {
        AssertUtil.notNull(scriptIds,SCRIPTID_NOTNULL);
        if(scriptIds.size() <=0) return new ArrayList<>();

        List<TaskReportChartVO> projectReportChart = mTestReportMapper.getProjectReportChartByModule(scriptIds);
        return projectReportChart == null?new ArrayList<>():projectReportChart;
    }

    @Override
    public List<TaskReportListVO> getProjectReportChartModuleExec(List<Integer> scriptIds,Integer projectId) {
        AssertUtil.notNull(scriptIds,SCRIPTID_NOTNULL);
        AssertUtil.notNull(projectId,"项目Id不允许为空");
        if(CollectionUtils.isEmpty(scriptIds)) return new ArrayList<>();

        List<TaskReportList> taskReportList = mTestReportMapper.getProjectReportChartModuleExec(projectId);
        if(taskReportList == null) return new ArrayList<>();

        List<ProjectModuleDTO> projectModule = null;
        ProjectModuleSearch search = new ProjectModuleSearch();
        search.setProjectId(projectId);
        projectModule = projectModuleMapper.select(search);

        List<TaskReportListVO> taskReportListVOList = new ArrayList<>();
        for(TaskReportList taskReport : taskReportList){
            TaskReportListVO vo = exist(taskReportListVOList,taskReport.getModuleId());
            if(vo == null){
                vo = new TaskReportListVO();
                vo.setPass(0);
                vo.setFail(0);
                vo.setModuleId(taskReport.getModuleId());
                taskReportListVOList.add(vo);
            }
            setModuleName(vo,projectModule);
            if(taskReport.getStatus() !=null && taskReport.getStatus().intValue() == 1)
                vo.setPass(taskReport.getCount());
            else if(taskReport.getStatus() !=null && taskReport.getStatus().intValue() == 0)
                vo.setFail(taskReport.getCount());
        }
        return taskReportListVOList;
    }

    private void transIds(List<String> scriptIds, List<Integer> ids){
        if(ids == null) ids = new ArrayList<>();
        if(CollectionUtils.isEmpty(scriptIds)) return;

        String[] tmp;
        for(String id : scriptIds){
            if(StringUtils.isEmpty(id)) continue;
            if(id.split(",").length > 0){
                tmp = id.split(",");
                for(String a :tmp){
                    ids.add(Integer.parseInt(a));
                }
            }
            else {
                ids.add(Integer.parseInt(id));
            }
        }
    }

    private void setModuleName(TaskReportListVO vo, List<ProjectModuleDTO> projectModule) {
        if(vo.getModuleId() == null) return;

        for(ProjectModuleDTO dto : projectModule){
            if(vo.getModuleId().equals(dto.getId())){
                vo.setModuleName(dto.getName());
                return;
            }
        }
    }

    private TaskReportListVO exist(List<TaskReportListVO> list,Integer moduleId){
        if(list != null){
            for(TaskReportListVO item : list){
                if(  moduleId == null && item.getModuleId()== null
                       ||  moduleId !=null && moduleId.equals(item.getModuleId())){
                    return item;
                }
            }
        }
        return null;
    }

    @Override
    public ResponseResult getTestReportDataByProject(Integer projectId) {

        AssertUtil.notNull(projectId,"项目ID不允许为空");

        List<Integer> scriptIds = this.getScriptIdsByProjectId(projectId);
        if(CollectionUtils.isEmpty(scriptIds)){
            return getCharData1(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), "chartExec");
        }
        List<ScriptInfo> scriptList = this.mTestReportMapper.getScriptsByIds(scriptIds);

        List<TaskReportChartVO> taskReportChartCategory = new ArrayList<>();
        List<TaskReportChartVO> taskReportChartModule = new ArrayList<>();
        this.transformTaskReport(scriptIds,scriptList,taskReportChartCategory,taskReportChartModule);
        List<TaskReportListVO> taskReportChartExec = this.getProjectReportChartModuleExec(scriptIds,projectId);

        return getCharData1(taskReportChartCategory, taskReportChartModule, taskReportChartExec, "chartExec");
    }

    private ResponseResult getCharData1(List<TaskReportChartVO> taskReportChartCategory, List<TaskReportChartVO> taskReportChartModule, List<TaskReportListVO> taskReportChartExec, String chartExec) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("chartCategory",taskReportChartCategory);
        jsonObject.put("chartModule",taskReportChartModule);
        jsonObject.put(chartExec,taskReportChartExec);
        ResponseResult responseResult = new ResponseResult(ResultCode.SUCCESS);
        responseResult.setData(jsonObject);
        return responseResult;
    }

    private ResponseResult getCharData1(List<TaskReportChartVO> taskReportChartCategory, List<TaskReportChartVO> taskReportChartModule, List<TaskReportListVO> taskReportChartExec, String chartExec
            ,String userName,String taskCreateTime,String projectName,List<TaskReportChartVO> taskReportExeCount) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("chartCategory",taskReportChartCategory);
        jsonObject.put("chartModule",taskReportChartModule);
        jsonObject.put(chartExec,taskReportChartExec);
        jsonObject.put("userName",userName);
        jsonObject.put("taskCreateTime",taskCreateTime);
        jsonObject.put("projectName",projectName);
        jsonObject.put("chartExeCount",taskReportExeCount);
        ResponseResult responseResult = new ResponseResult(ResultCode.SUCCESS);
        responseResult.setData(jsonObject);
        return responseResult;
    }


    @Override
    public ResponseResult getTestReportDataByTask(Integer taskId) {
        AssertUtil.notNull(taskId,TASKID_NOTNULL);

        // 根据 taskId 查询已执行任务列表
        List<TaskDTO> taskDTOs = taskMapper.queryByProjectId(taskId);
        if (CollectionUtils.isEmpty(taskDTOs)) {
            throw new CustomException(ResultCode.DATA_IS_WRONG);
        }

        TaskDTO lastTaskHistoryByTaskId = taskDTOs.get(0);
        taskId = lastTaskHistoryByTaskId.getId();
        if(lastTaskHistoryByTaskId.getType() == 3||lastTaskHistoryByTaskId.getType() == 4) {
            return ResponseResult.defaultSuccess(null);
        }
        //--------------------------------------------------------------------------------------------------------------------------------

        TaskDTO taskHistoryById = taskService.getTaskHistoryById2(taskId);
        AssertUtil.notNull(taskHistoryById,"查无任务数据");

        String[] scriptIds = taskHistoryById.getScriptIds().split(",");
        List<Integer> idsList = Arrays.stream(scriptIds).map(s->Integer.parseInt(s.trim())).collect(Collectors.toList());
        List<ScriptInfo2> scriptInfos = iScriptInfoServcie.selectScriptByScriptIdsWithoutStatus(idsList);
        if(CollectionUtils.isEmpty(scriptInfos)) throw new CustomException(ResultCode.BUSINESS_PROJECT_SCRIPT_NOT_EXISTED);


        List<TaskReportChartVO> taskReportCategoryChart = this.getTaskReportCategoryChart2(idsList,scriptInfos);
        List<TaskReportChartVO> taskReportModuleChart = this.getTaskReportModuleChart2(idsList,scriptInfos);
        List<TaskReportListVO> taskReportList = this.getTaskReportList(taskDTOs);
        //
        List<TaskReportChartVO> taskReportExeCount = getTaskReportChartExeCount(taskHistoryById); // ok

        // 累加计划执行次数，脚本类型和模块
        this.accumulationTaskReport(taskReportCategoryChart, taskHistoryById.getExePlanTimes());
        this.accumulationTaskReport(taskReportModuleChart, taskHistoryById.getExePlanTimes());

        return getCharData1(taskReportCategoryChart, taskReportModuleChart, taskReportList, "list"
                ,taskHistoryById.getUserName(),
                taskHistoryById.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                taskHistoryById.getProjectName(),taskReportExeCount);
    }

    private void accumulationTaskReport(List<TaskReportChartVO> taskReportCategoryChart, Integer exePlanTimes) {
        if (null != exePlanTimes && exePlanTimes > 0) {
            for (TaskReportChartVO taskReportChartVO : taskReportCategoryChart) {
                taskReportChartVO.setCount(taskReportChartVO.getCount() * exePlanTimes);
            }
        }
    }

    @Autowired
    private SubtaskDistributeMapper subtaskDistributeMapper;

    private List<TaskReportChartVO> getTaskReportChartExeCount(TaskDTO taskHistoryById) {
        if(taskHistoryById.getExePlanTimes() == null) taskHistoryById.setExePlanTimes(0);
        // 获取当前Id的所有成功执行的数量
        Integer successCount = mTestReportMapper.getTaskSuccessByParentId(taskHistoryById.getId());
        if(successCount == null) successCount = 0;

        // 获取当前Id的所有失败执行的数量
        Integer failCount = mTestReportMapper.getTaskFailByParentId(taskHistoryById.getId());
        if(failCount == null) failCount = 0;
        Integer totalCount = taskHistoryById.getExeNumber();
        // 获取当前所有尚未执行（未执行完成）执行的数量
        SubtaskDistributeExample sdExample = new SubtaskDistributeExample();
        sdExample.createCriteria().andTaskIdEqualTo(Long.valueOf(taskHistoryById.getId()));
        List<SubtaskDistribute> subtaskDistributes = subtaskDistributeMapper.selectByExample(sdExample);
        if(!CollectionUtils.isEmpty(subtaskDistributes)){
            SubtaskDistribute sd = subtaskDistributes.get(0);
            totalCount = sd.getNeedExecSum();
        }
        Integer waitCount = totalCount - successCount - failCount;
        List<TaskReportChartVO> taskReportExeCount = new ArrayList<>();
        TaskReportChartVO totalCountVo = new TaskReportChartVO("totalCount", totalCount);
        TaskReportChartVO successCountVo = new TaskReportChartVO("successCount", successCount);
        TaskReportChartVO failCountVo = new TaskReportChartVO("failCount", failCount);
        TaskReportChartVO waitCountVo = new TaskReportChartVO("waitCount", waitCount);
        taskReportExeCount.add(totalCountVo);
        taskReportExeCount.add(successCountVo);
        taskReportExeCount.add(failCountVo);
        taskReportExeCount.add(waitCountVo);
        return taskReportExeCount;
    }

    @Override
    public ResponseResult getTestReportDataByTaskScripts(Integer taskId) {
        AssertUtil.notNull(taskId,TASKID_NOTNULL);

        //  临时处理，传入的taskId是t_task.id (应该是t_task_history.id),暂时行通过t_task.id 转换最后一次t_task_history.id，并查询数据
        TaskDTO lastTaskHistoryByTaskId = taskService.getLastTaskHistoryByTaskId(taskId);
        if(lastTaskHistoryByTaskId == null) throw new CustomException(ResultCode.DATA_IS_WRONG);
        taskId = lastTaskHistoryByTaskId.getId();
        //--------------------------------------------------------------------------------------------------------------------------------

        TaskDTO taskHistoryById = taskService.getTaskHistoryById2(taskId);
        AssertUtil.notNull(taskHistoryById,"查无任务数据");

        String[] scriptIds = taskHistoryById.getScriptIds().split(",");
        List<Integer> idsList = Arrays.stream(scriptIds).map(s->Integer.parseInt(s.trim())).collect(Collectors.toList());
        List<ScriptInfo2> scriptInfos = iScriptInfoServcie.selectScriptByScriptIdsWithoutStatus(idsList);
        if(CollectionUtils.isEmpty(scriptInfos)) throw new CustomException(ResultCode.DATA_IS_WRONG);

        // 填充最近修改人、修改时间
        ScriptInfoHistory scriptInfoHistory;
        for(ScriptInfo2 info : scriptInfos){
            info.setUpdateStatus(1);
            info.setUpdateUserName(info.getCreateUserName());
            info.setTimeUpdate(info.getTimeCreate());

            scriptInfoHistory = scriptInfoHistoryMapper.selectLastByScriptId(info.getId());
            if(scriptInfoHistory != null){
                info.setUpdateStatus(scriptInfoHistory.getStatus());
                info.setUpdateUserName(scriptInfoHistory.getUserName());
                info.setTimeUpdate(scriptInfoHistory.getCreateTime());
            }
        }

        List<ScriptInfo2> result = new ArrayList<>();
        for (Integer scriptId : idsList){
            for(ScriptInfo2 info : scriptInfos){
                if(scriptId.intValue() == info.getId().intValue()){
                    result.add(info);
                }
            }
        }

        return ResponseResult.defaultSuccess(result);
    }

    @Override
    public ResponseResult getFailReports(Integer taskId, Integer moduleId) {
        AssertUtil.notNull(taskId,TASKID_NOTNULL);
        AssertUtil.notNull(moduleId,"模块ID不允许为空");

        String key = REDIS_KEY_FAIL_REPORT + taskId + ":"+moduleId;
        String cacheData = iRedisService.get(key);
        if(!StringUtils.isEmpty(cacheData)){
            try {
                return ResponseResult.defaultSuccess(JSON.parseObject(cacheData, new TypeReference<List<TestReport>>() {
                }));
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        // TODO 临时处理，传入的taskId是t_task.id (应该是t_task_history.id),暂时行通过t_task.id 转换最后一次t_task_history.id，并查询数据
        TaskDTO lastTaskHistoryByTaskId = taskService.getLastTaskHistoryByTaskId(taskId);
        if(lastTaskHistoryByTaskId == null) throw new CustomException(ResultCode.DATA_IS_WRONG);
        taskId = lastTaskHistoryByTaskId.getId();

        List<TestReport> list = mTestReportMapper.getFailReports(taskId, moduleId);
        if(!CollectionUtils.isEmpty(list)) {
            iRedisService.setex(key, JSON.toJSONString(list) , TimeUnit.SECONDS, iRedisService.getExpire(REDIS_CACHE_EXPIRE, 60));
        }

        return ResponseResult.defaultSuccess(list);
    }

    @Override
    public ResponseResult getFileLog(String fileName) {
        try {
            String retLog = null;
//            StreamResponse streamResponse = fileTemplate.getFileStream(fileName);
//            if (null != streamResponse) {
//                InputStream is = streamResponse.getInputStream();
//                ByteArrayOutputStream result = new ByteArrayOutputStream();
//                byte[] buffer = new byte[1024];
//                int length;
//                while ((length = is.read(buffer)) != -1) {
//                    result.write(buffer, 0, length);
//                }
//                retLog = result.toString(StandardCharsets.UTF_8.name());
//                IOUtils.closeQuietly(result, is);
//            }

            InputStream is = minioUtils.getObjectInputStream(fileName);
            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = is.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            retLog = result.toString(StandardCharsets.UTF_8.name());
            result.close();
            is.close();
            return ResponseResult.defaultSuccess(retLog);
        } catch (Exception e) {
            log.error("getFileLog error: ", e);
            return new ResponseResult(ResultCode.SYSTEM_INNER_ERROR);
        }
    }

    private void transformTaskReport(List<Integer> scriptIds, List<ScriptInfo> scriptList, List<TaskReportChartVO> taskReportChartCategory, List<TaskReportChartVO> taskReportChartModule) {
        if(!CollectionUtils.isEmpty(scriptIds) && !CollectionUtils.isEmpty(scriptList)){
            Map<String,Integer> map1 = new HashMap<>();
            Map<String,Integer> map2 = new HashMap<>();
            for(int i=0;i<scriptIds.size();i++){
                for (int j = 0; j < scriptList.size() ; j++) {
                    if(scriptIds.get(i).intValue() == scriptList.get(j).getId().intValue()){
                        // 找到脚本

                        // 按类别统计
                        if(!map1.containsKey(scriptList.get(j).getScriptCategory())){
                            map1.put(scriptList.get(j).getScriptCategory(),1);
                        }
                        else{
                            map1.put(scriptList.get(j).getScriptCategory(),map1.get(scriptList.get(j).getScriptCategory())+1);
                        }
                        // 按模块统计
                        if(!map2.containsKey(scriptList.get(j).getProModuleName())){
                            map2.put(scriptList.get(j).getProModuleName(),1);
                        }
                        else{
                            map2.put(scriptList.get(j).getProModuleName(),map2.get(scriptList.get(j).getProModuleName())+1);
                        }
                        break;
                    }
                }
            }
            for (Map.Entry<String, Integer> entry : map1.entrySet()) {
                taskReportChartCategory.add(new TaskReportChartVO(entry.getKey(),entry.getValue()));
            }
            for (Map.Entry<String, Integer> entry : map2.entrySet()) {
                taskReportChartModule.add(new TaskReportChartVO(entry.getKey(),entry.getValue()));
            }
        }
    }

    @Override
    public List<TestReportErrorVideoInfo> getErrorVideoInfosByTestReportId(Integer testReportId) {
        TestReportErrorVideoInfoExample example = new TestReportErrorVideoInfoExample();
        example.createCriteria().andTestReportIdEqualTo(testReportId);
        return testReportErrorVideoInfoMapper.selectByExample(example);
    }

    @Autowired
    private TaskColdHotStartupLogMapper taskColdHotStartupLogMapper;

    @Override
    public List<TestReportApplicationResponseTime> getTestReportApplicationResponseTime(Integer testReportId) {
        TestReportApplicationResponseTimeExample example = new TestReportApplicationResponseTimeExample();
        example.createCriteria().andTestReportIdEqualTo(testReportId);
        return testReportApplicationResponseTimeMapper.selectByExample(example);
    }

    @Override
    public List<TaskStartupInfo> getTaskStartupInfo(Integer taskId) {
        TaskDTO taskHistoryById = taskMapper.getTaskHistoryById(taskId);
        List<TaskStartupInfo> taskStartupInfos = taskColdHotStartupLogMapper.selectStatisticByTaskId(taskHistoryById.getParentId());
        return taskStartupInfos;
    }

}
